package cn.xuqiudong.work.baidu.helper;

import cn.xuqiudong.common.base.craw.BaseCrawl;
import cn.xuqiudong.common.util.JsonUtil;
import cn.xuqiudong.work.baidu.model.*;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.HttpStatusException;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 描述:
 * 百度翻译 ICBCSTL-96358
 *
 * @author Vic.xu
 * @since 2024-12-25 16:53
 */
public class BaiduTranslateHelper extends BaseCrawl {

    /**
     * 分隔符：字段名称 +  QUERY_SEPARATOR
     * ====name====:
     */
    private static final String QUERY_SEPARATOR_PREFIX = "====";
    private static final String QUERY_SEPARATOR_SUFFIX = "====:";
    /**
     * 提取翻译后的正则 group(2)
     */
    private static final String FETCH_REGEX = QUERY_SEPARATOR_PREFIX + "(.*?)"  + QUERY_SEPARATOR_SUFFIX + "(.*)";
    private static final Pattern FETCH_PATTERN = Pattern.compile(FETCH_REGEX);
    

    private static final String TRANSLATE_URL = "https://fanyi-preview.baidu.com/privatize/api/v1/text/translate";

    private static final String TERM_ID = "yv43ZkWqo7";

    private static final String FROM = "zh";
    private static final String TO = "en";

    public static void main(String[] args) throws Exception {
        String s = System.lineSeparator();
        System.out.println(s);
        TestTranslateVO translateVO = new TestTranslateVO();
        translateVO.setTitle("运营管理");
        translateVO.setContent("新增功能包括用户管理、权限设置、\n报告生成等");
        translateVO.setNote("修复了若干bug");
        JsonUtil.printJson(translateVO);
        Object translate = translate(translateVO);
        JsonUtil.printJson(translate);
    }


    public static <T> Object translate(T vo) throws Exception {
        FieldMetaInfo4Object fieldMetaInfo4Object = fetchFieldMetaMap(vo);
        String query = fieldMetaInfo4Object.getQuery();
        if (StringUtils.isBlank(query)) {
            return vo;
        }
        TranslationResponse response = request(query);
        if (response == null) {
            return vo;
        }
        if (response.getErrno() == 0) {
            List<TranslationResponse.TransResult> transResults = response.getData().getTrans_result();
            // 处理翻译结果，将字段名与翻译段落合并
            Map<String, String> fieldTranslations = processTranslationResult(transResults, fieldMetaInfo4Object.getFieldMetaMap());

            T newVo = (T) vo.getClass().newInstance();
            // 填充新的VO对象
            fillVoWithTranslation(newVo, fieldTranslations, fieldMetaInfo4Object.getFieldMetaMap());
            return newVo;
        }

        return vo;
    }


    public static TranslationResponse request(String query) throws IOException {
        try {
            TranslateQueryVO translateQueryVO = new TranslateQueryVO(query, FROM, TO, TERM_ID);
            String json = JsonUtil.toJson(translateQueryVO);
            System.out.println("q=\n\t" + json);
            String result = new BaiduTranslateHelper().con(TRANSLATE_URL)
                    .header("Content-Type", "application/json")
                    .requestBody(json)
                    .postBodyText();
            System.out.println(result);
            return JsonUtil.jsonToObject(result, TranslationResponse.class);
        } catch (HttpStatusException e) {
            e.printStackTrace();
            // 捕获 HTTP 状态异常并获取状态码
            int statusCode = e.getStatusCode();
            String localizedMessage = e.getLocalizedMessage();
            System.out.println("请求失败，HTTP 状态码: " + statusCode + "  localizedMessage =" + localizedMessage);
        } catch (Exception e) {
            System.out.println("请求失败");
            e.printStackTrace();
        }
        return null;
    }


    // 生成分隔符
    private static String generateSeparator(Object index) {
        return QUERY_SEPARATOR_PREFIX + index + QUERY_SEPARATOR_SUFFIX;
    }


    /**
     * 处理翻译结果，将字段名与翻译段落合并
     */
    public static Map<String, String> processTranslationResult(List<TranslationResponse.TransResult> transResults, Map<String, FieldMeta> fieldMetaMap) {
        Map<String, String> fieldTranslations = new LinkedHashMap<>();
        String currentFieldName = null;
        StringBuilder combinedText = new StringBuilder();

        // 遍历翻译结果
        for (TranslationResponse.TransResult result : transResults) {
            String translatedText = result.dst;
            FieldMeta fieldMeta = getFieldFromTranslation(result.src, fieldMetaMap);

            // 如果找到了新的字段 (fieldMeta 不为 null)
            if (fieldMeta != null) {
                // 如果当前有正在处理的字段，保存翻译结果
                if (currentFieldName != null) {
                    fieldTranslations.put(currentFieldName, combinedText.toString().trim());
                }

                // 更新当前字段为新的字段
                currentFieldName = fieldMeta.getFieldName();
                // 去除分隔符后的翻译文本
                translatedText = getTranslateTextBySeparator(translatedText, fieldMeta);
                // 重置 StringBuilder
                combinedText.setLength(0);
            }

            // 如果没有找到新的字段 (fieldMeta 为 null)，并且当前有处理中的字段 (currentFieldName 不为 null)
            if (currentFieldName != null) {
                combinedText.append(translatedText).append(System.lineSeparator());
            }
            // 如果既没有找到字段 (fieldMeta 为 null)，也没有处理中的字段 (currentFieldName 为 null)，则忽略这段翻译数据
        }

        // 最后保存翻译的字段
        if (currentFieldName != null) {
            fieldTranslations.put(currentFieldName, combinedText.toString().trim());
        }

        return fieldTranslations;
    }

    /**
     * 获取去除分隔符后的翻译文本： 需要考虑分隔符被翻译的情况
     */
    private static String getTranslateTextBySeparator(String desc, FieldMeta fieldMeta){
        if (StringUtils.isBlank(desc)) {
            return desc;
        }
        String separator = fieldMeta.getSeparator();
        // 当翻译后的分隔符没有改变的时候 直接截取
        if (StringUtils.startsWithIgnoreCase(desc, fieldMeta.getSeparator())) {
            return desc.substring(separator.length());
        }
        // 如果没有匹配到字段，返回 null
        Matcher matcher = FETCH_PATTERN.matcher(desc);
        // 如果匹配成功
        if (matcher.find()) {
            // 提取翻译后的文本（第二个捕获组）
            return matcher.group(2);
        }
        return desc.substring(separator.length());

    }

    /**
     * 动态填充 VO 对象的字段，使用元数据中的字段信息
     */
    public static void fillVoWithTranslation(Object vo, Map<String, String> translatedFields, Map<String, FieldMeta> fieldMetaMap) {
        // 遍历元数据中的字段
        for (Map.Entry<String, FieldMeta> entry : fieldMetaMap.entrySet()) {
            String fieldName = entry.getKey();
            FieldMeta fieldMeta = entry.getValue();

            // 如果翻译结果中包含该字段的翻译
            if (translatedFields.containsKey(fieldName)) {
                String translatedValue = translatedFields.get(fieldName);

                try {
                    // 通过元数据中的字段信息动态填充 VO 字段
                    if (fieldMeta != null && fieldMeta.getField() != null) {
                        // 获取字段并填充
                        fieldMeta.getField().set(vo, translatedValue);
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();  // 处理反射异常
                }
            }
        }
    }


    /**
     * 从翻译结果中获取对应的 FieldMeta 对象
     */
    private static FieldMeta getFieldFromTranslation(String src, Map<String, FieldMeta> fieldMetaMap) {
        // 遍历元数据，查找对应的字段
        for (Map.Entry<String, FieldMeta> entry : fieldMetaMap.entrySet()) {
            FieldMeta fieldMeta = entry.getValue();
            if (StringUtils.startsWithIgnoreCase(src, fieldMeta.getSeparator())) {
                // 找到对应的字段，返回 FieldMeta
                return fieldMeta;
            }
        }
        // 如果没有匹配到字段，返回 null
        return null;
    }


    /**
     * 获取VO的字段的元数据
     */
    public static FieldMetaInfo4Object fetchFieldMetaMap(Object vo) throws IllegalAccessException {
        Map<String, FieldMeta> fieldMetaMap = new HashMap<>();
        StringBuilder query = new StringBuilder();
        // 获取VO类的所有字段，包括私有字段
        Field[] fields = vo.getClass().getDeclaredFields();
        int index = 0;
        for (Field field : fields) {
            field.setAccessible(true);  // 允许访问私有字段
            String fieldName = field.getName();  // 获取字段名
            Object fieldValue = field.get(vo);   // 获取字段的值
            // 判断字段值是否为空
            boolean isEmpty = (fieldValue == null || "".equals(fieldValue));
            if (!isEmpty) {
                // 创建 FieldMeta 对象并存储
                index++;
                FieldMeta fieldMeta = new FieldMeta(field, fieldName, fieldValue, isEmpty, generateSeparator(index), index);
                fieldMetaMap.put(fieldName, fieldMeta);
                query.append(fieldMeta.getSeparator()).append(fieldValue).append("\n");
            }
        }
        return new FieldMetaInfo4Object(fieldMetaMap, query.toString());
    }



    @Override
    protected int getTimeout() {
        return 30000;
    }


}
